package com.twu.biblioteca;

import java.util.LinkedHashMap;
import java.util.Map;

public class Menu {

    private Map<String, MenuOption> options;


    private static final String INSTRUCTIONS = "\nPlease enter an option and hit ENTER\n";
    private static final String PROMPT = "---> ";
    private boolean authenticated;

    public Menu() {
        options = new LinkedHashMap<>();
        authenticated = false;
    }

    public String welcomeUser() {
        return "Welcome!\n";
    }

    public void registerOption(String letter, String name, Command command) {
        options.put(letter, new MenuOption(letter, name, command));
    }

    public void registerOption(String letter, String name, Command command, String... inputs) {
        options.put(letter, new MenuOption(letter, name, command, inputs));
    }

    public MenuOption getOption(String key) {
        MenuOption option = options.get(key);

        if (option != null) {
            boolean authOnlyCondition = option.isAuthOnly() && !isAuthenticated();
            boolean noAuthOnlyCondition = option.isNoAuthOnly() && isAuthenticated();
            if (authOnlyCondition || noAuthOnlyCondition) {
                option = null;
            }
        }

        return option;
    }

    public String printMenu() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(INSTRUCTIONS);
        for (MenuOption option : options.values()) {
            if(!isAuthenticated()) {
                if (option.isAuthOnly()) {
                    continue;
                }
            } else {
                if (option.isNoAuthOnly()) {
                    continue;
                }
            }

            stringBuilder.append(String.format("  (%s) %s\n",
                    option.getLetter(), option.getName()));
        }

        return stringBuilder.append(PROMPT).toString();
    }

    public String parseOption(String input) {
        return input.trim().substring(0, 1).toUpperCase();
    }

    public String callOption(String letter, Object[] arguments) throws ExitException {
        return getOption(letter).callCommand(arguments);
    }

    public String[] chooseOption(String letter) {
        MenuOption option = getOption(letter);

        if (option.getInputs() == null) {
            return null;
        }

        return option.getInputs();
    }

    public boolean isAuthenticated() {
        return authenticated;
    }

    public void setAuthenticated(boolean authenticated) {
        this.authenticated = authenticated;
    }

    public void makeAuthOnly(String letter) {
        getOption(letter).makeAuthOnly();
    }

    public void makeNoAuthOnly(String letter) {
        getOption(letter).makeNoAuthOnly();
    }

    public Map<String, MenuOption> getOptions() {
        return options;
    }
}
